package com.kamistoat.ruoyi.ruoyimodulessystem.controller;

import java.util.List;
import java.util.stream.Collectors;

import com.kamistoat.ruoyi.ruoyiapisystem.domain.SysConfig;
import com.kamistoat.ruoyi.ruoyicommoncore.utils.StringUtils;
import com.kamistoat.ruoyi.ruoyicommoncore.utils.poi.ExcelUtil;
import com.kamistoat.ruoyi.ruoyicommoncore.web.controller.BaseController;
import com.kamistoat.ruoyi.ruoyicommoncore.web.domain.AjaxResult;
import com.kamistoat.ruoyi.ruoyicommoncore.web.page.TableDataInfo;
import com.kamistoat.ruoyi.ruoyicommonlog.annotation.Log;
import com.kamistoat.ruoyi.ruoyicommonlog.enums.BusinessType;
import com.kamistoat.ruoyi.ruoyicommonsecurity.annotation.RequiresPermissions;
import com.kamistoat.ruoyi.ruoyicommonsecurity.utils.SecurityUtils;
import com.kamistoat.ruoyi.ruoyimodulessystem.service.SysConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.kamistoat.ruoyi.ruoyiapisystem.entity.SysConfigEntity;

import javax.servlet.http.HttpServletResponse;


/**
 * 参数配置表。
 * mybatis-plus原生三件套，该文件夹下的Controller全部都是相同概念
 *
 * @author kamistoat
 * @email linjianshanke@163.com
 * @date 2022-08-09 10:34:46
 */
@RestController
@RequestMapping("/config")
public class SysConfigController extends BaseController {
    @Autowired
    private SysConfigService sysConfigService;


    /**
     * 获取匹配的参数配置列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("system:config:list")
    public TableDataInfo list(SysConfig sysConfig) {
        startPage();
        List<SysConfigEntity> sysConfigEntityList = sysConfigService.selectConfigList(
                StringUtils.isNull(sysConfig) ? new SysConfig() : sysConfig);
        return getDataTable(entity2Vo(sysConfigEntityList));
    }

    /**
     * 获取全部参数配置列表
     */
    @RequestMapping("/list/all")
    @RequiresPermissions("system:config:list")
    public TableDataInfo listAll(SysConfig sysConfig) {
        startPage();
        List<SysConfigEntity> sysConfigEntityList = sysConfigService.list();
        return getDataTable(entity2Vo(sysConfigEntityList));
    }

    /**
     * 导出匹配的参数配置列表
     */
    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:config:export")
    @PostMapping("/export")
    public void export(HttpServletResponse httpServletResponse, SysConfig config) {
        List<SysConfigEntity> sysConfigEntityList = sysConfigService.selectConfigList(config);
        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
        util.exportExcel(httpServletResponse, entity2Vo(sysConfigEntityList), "参数数据");
    }

    /**
     * 导出全部的参数配置列表
     */
    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:config:export")
    @PostMapping("/export/all")
    public void exportAll(HttpServletResponse httpServletResponse) {
        List<SysConfigEntity> sysConfigEntityList = sysConfigService.list();
        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
        util.exportExcel(httpServletResponse, entity2Vo(sysConfigEntityList), "参数数据");
    }


    /**
     * 根据id查询对应entity
     */
    @RequestMapping("/{configId}")
    public AjaxResult info(@PathVariable("configId") Integer configId) {
        SysConfigEntity sysConfigEntity = sysConfigService.getById(configId);
        return AjaxResult.success(entity2Vo(sysConfigEntity));
    }

    /**
     * 根据key查询这个key对应的value，注意不是entity。
     */
    @RequestMapping("/configKey/{configKey}")
    public AjaxResult getConfigKey(@PathVariable("configKey") String configKey) {
        String configValue = sysConfigService.selectConfigByKey(configKey);
        return AjaxResult.success();
    }


    /**
     * 新增参数配置。
     * 直接向 "ruoyimodulessystem/sysconfig" 发送post请求
     * 开启 @Validated 参数体校验
     */
    @PostMapping
    @RequiresPermissions("system:config:add")
    @Log(title = "参数管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@Validated @RequestBody SysConfig sysConfig) {
        if (sysConfigService.checkConfigKeyUnique(sysConfig)) {
            return AjaxResult.error("新增参数'" + sysConfig.getConfigName() + "'失败，参数key'" + sysConfig.getConfigKey() + "'已存在");
        }
        sysConfig.setCreateBy(SecurityUtils.getUserName());
        return toAjax(sysConfigService.saveAndCache(vo2Entity(sysConfig)));
    }


    /**
     * 修改参数牌配置
     */
    @RequiresPermissions("system:config:edit")
    @Log(title = "参数管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysConfig sysConfig) {
        if (StringUtils.isNull(sysConfig) || StringUtils.isNull(sysConfig.getConfigId())) {
            return AjaxResult.error("失败，不能对空对象提交修改");
        }
        if (sysConfigService.checkConfigKeyUnique(sysConfig)) {
            return AjaxResult.error("修改参数'" + sysConfig.getConfigName() + "'失败，参数key'" + sysConfig.getConfigKey() + "'已存在");
        }
        sysConfig.setUpdateBy(SecurityUtils.getUserName());
        return toAjax(sysConfigService.updateByIdAndCache(vo2Entity(sysConfig)));
    }

    /**
     * 删除参数配置
     */
    @RequiresPermissions("system:config:remove")
    @Log(title = "参数管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{configIds}")
    public AjaxResult remove(@PathVariable Long[] configIds) {
        return toAjax(sysConfigService.deleteConfigByIdsAndRemoveCache(configIds));
    }

    /**
     * 刷新参数缓存
     */
    @RequiresPermissions("system:config:remove")
    @Log(title = "参数管理", businessType = BusinessType.CLEAN)
    @RequestMapping("/refreshCache")
    public AjaxResult refreshCache() {
        sysConfigService.resetConfigCache();
        return AjaxResult.success();
    }


    /**
     * Entity 和 Vo类的转换
     */
    private List<SysConfig> entity2Vo(List<SysConfigEntity> sysConfigEntityList) {
        return
                sysConfigEntityList.stream().map(sysConfigEntity -> {
                    SysConfig sysConfigVo = new SysConfig();
                    BeanUtils.copyProperties(sysConfigEntity, sysConfigVo);
                    return sysConfigVo;
                }).collect(Collectors.toList());
    }

    private SysConfig entity2Vo(SysConfigEntity sysConfigEntity) {
        SysConfig sysConfigVo = new SysConfig();
        BeanUtils.copyProperties(sysConfigEntity, sysConfigVo);
        return sysConfigVo;
    }

    private List<SysConfigEntity> vo2Entity(List<SysConfig> sysConfigList) {
        return
                sysConfigList.stream().map(sysConfig -> {
                    SysConfigEntity sysConfigEntity = new SysConfigEntity();
                    BeanUtils.copyProperties(sysConfig, sysConfigEntity);
                    return sysConfigEntity;
                }).collect(Collectors.toList());
    }

    private SysConfigEntity vo2Entity(SysConfig sysConfig) {
        SysConfigEntity sysConfigEntity = new SysConfigEntity();
        BeanUtils.copyProperties(sysConfig, sysConfigEntity);
        return sysConfigEntity;
    }
}
